// 状态码
const codeMessage = {
  200: '请求成功',
  201: '新建或修改数据成功',
  202: '请求后台排队',
  204: '删除数据成功',
  400: '发出请求有误，服务器没有进行新建或修改数据的操作',
  401: '用户没有权限',
  403: '访问禁止',
  404: '请求地址错误',
  406: '请求格式不正确',
  410: '请求资源删除',
  422: '验证错误',
  500: '服务器错误',
  502: '网关错误',
  503: '服务器过载',
  504: '网关超时'
};

const defaultOptions = {
  timeout: 1000 * 30,
  headers: {
    'Content-Type': 'application/json;charset=utf-8'
  },
  baseURL: ''
};

const errorHandler = error => {
  if (error.response){
    console.log(codeMessage[error.response.status] || '未知错误');
  }
  return Promise.reject(error);
};

// 请求拦截
const requestInterceptor = (config) => {
  const newConfig = {...config};
  newConfig.url = `${defaultOptions.baseURL}${config.url}`;
  // const token = window.localStorage.getItem('token');
  // if (token){
  //   newConfig.headers.append('Authorization', `Bearer ${token}`);
  // }
  return newConfig;
};

// 响应拦截
const responseInterceptor = (response) => {
  console.log(response);
  if (response.ok && response.status >= 200 && response.status < 400){
    return response.json();
  } else {
    throw response;
  }
};

function fetchContainer(url, options = {}){
  const config = requestInterceptor({...defaultOptions, ...options, url});
  const controller = new AbortController();
  const { signal } = controller;
  const timeoutId = setTimeout(() => controller.abort(), config.timeout);
  return fetch(config.url, { ...config, signal})
    .then((response) => {
      return responseInterceptor(response);
    })
    .catch((error) => {
      if (error.name = 'AbortError'){
        console.error('请求超时');
      }
      return errorHandler(error)
    })
    .finally(() => {
      clearTimeout(timeoutId);
    })
}

class APIClient {
  get(url, options = {}){
    return fetchContainer(url, {...options, method: 'GET'});
  }
  post(url, body, options = {}){
    return fetchContainer(url, {...options, method: 'POST', body: JSON.stringify(body)});
  }
  put(url, body, options = {}){
    return fetchContainer(url, {...options, method: 'PUT', body: JSON.stringify(body)});
  }
  delete(url, options = {}){
    return fetchContainer(url, {...options, method: 'DELETE'});
  }
}

export default new APIClient();